package com.ssy.lingxi.contract.component;

import lombok.extern.slf4j.Slf4j;
import org.jodconverter.core.DocumentConverter;
import org.jodconverter.core.document.DefaultDocumentFormatRegistry;
import org.jodconverter.core.document.DocumentFormat;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.*;

/**
 *
 * @author yzc
 * @version 2.0.0
 * @date 2020/9/10
 */
@Slf4j
@Service
public class OfficeConvertService {

    @Resource
    private DocumentConverter documentConverter;

    /**
     * @param inputStream  源文件输入流
     * @param outputStream pdf目标输出流
     */
    public void convert(InputStream inputStream, OutputStream outputStream, String suffix, String toSuffix) throws Exception {
        final DocumentFormatEnum documentFormatEnum = DocumentFormatEnum.valueOf(suffix.toUpperCase());

        long startTime = System.currentTimeMillis();
        try (final InputStream is = documentFormatEnum.getInputStream(inputStream)) {
            final DocumentFormat format = documentFormatEnum.getFormFormat();
            final DocumentFormat targetFormat = getDocumentFormat(toSuffix);

            log.info("待转换的文档类型：{}, ====>> 转换的目标文档类型：{}", format, targetFormat);
            documentConverter.convert(is).as(format).to(outputStream).as(targetFormat).execute();
        }
        long endTime = System.currentTimeMillis();
        log.info("文档转换结束, 耗费时间: {}秒", (endTime - startTime) / 1000);

    }

    public enum DocumentFormatEnum {
        DOC {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.DOC;
            }
        },
        DOCX {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.DOCX;
            }
        },
        PPT {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.PPT;
            }
        },
        PPTX {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.PPTX;
            }
        },
        XLS {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.XLS;
            }

            @Override
            public DocumentFormat getTargetFormat() {
                return DefaultDocumentFormatRegistry.HTML;
            }
        },
        XLSX {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.XLSX;
            }

            @Override
            public DocumentFormat getTargetFormat() {
                return DefaultDocumentFormatRegistry.HTML;
            }
        },
        TXT {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.TXT;
            }

            @Override
            public InputStream getInputStream(InputStream inputStream) throws IOException {
                //因为会出现中文乱码问题，所以先通过字符流进行编码转换，再转换成字节流
                try (final BufferedReader bis = new BufferedReader(new InputStreamReader(inputStream, "GBK"))) {
                    StringBuffer buf = new StringBuffer();
                    String temp;
                    while ((temp = bis.readLine()) != null) {
                        buf.append(temp).append(System.getProperty("line.separator"));
                    }
                    return new ByteArrayInputStream(buf.toString().getBytes());
                }
            }
        },
        PDF {
            @Override
            public DocumentFormat getFormFormat() {
                return DefaultDocumentFormatRegistry.PDF;
            }

            @Override
            public DocumentFormat getTargetFormat() {
                return DefaultDocumentFormatRegistry.HTML;
            }
        },
        ;

        public InputStream getInputStream(InputStream inputStream) throws IOException {
            return inputStream;
        }

        public abstract DocumentFormat getFormFormat();

        public DocumentFormat getTargetFormat() {
            return DefaultDocumentFormatRegistry.HTML;
        }
    }

    private DocumentFormat getDocumentFormat(String suffix) {
        switch (suffix.toUpperCase()) {
            case "DOC":
                return DefaultDocumentFormatRegistry.DOC;
            case "DOCX":
                return DefaultDocumentFormatRegistry.DOCX;
            case "PPT":
                return DefaultDocumentFormatRegistry.PPT;
            case "PPTX":
                return DefaultDocumentFormatRegistry.PPTX;
            case "XLS":
                return DefaultDocumentFormatRegistry.XLS;
            case "XLSX":
                return DefaultDocumentFormatRegistry.XLSX;
            case "TXT":
                return DefaultDocumentFormatRegistry.TXT;
            case "PDF":
                return DefaultDocumentFormatRegistry.PDF;
            case "HTML":
                return DefaultDocumentFormatRegistry.HTML;
            default:
                throw new IllegalArgumentException("can't not found document format");
        }
    }
}
